﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using System.Collections;

using FCNS.KeepMoney.Util;
using FCNS.KeepMoney.Configuration;
using FCNS.KeepMoneyLibrary.Data;

namespace FCNS.KeepMoney.UI
{
    public partial class GtdViewDefault : Control, IGtdView
    {
        public GtdViewDefault()
        {
            InitializeComponent();

            this.SetStyle(ControlStyles.DoubleBuffer, true);
            this.SetStyle(ControlStyles.UserPaint, true);
            this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
            this.SetStyle(ControlStyles.UserMouse, true);
            this.SetStyle(ControlStyles.ResizeRedraw, false);
            this.SetStyle(ControlStyles.Opaque, true);

            unFinish = Properties.Resources.circle_16;
            finish = Properties.Resources.right_16;
            levelNull = Properties.Resources.star_black__16;
            level = Properties.Resources.star_yellow_16;
            note = Properties.Resources.note_16;
            close = Properties.Resources.close_16;
            clock = Properties.Resources.clock_16;

            vScrollBar1.Parent = this;
            vScrollBar1.Width = 15;
            vScrollBar1.Dock = DockStyle.Right;

            this.MouseWheel += new MouseEventHandler(GtdViewDefault_MouseWheel);
        }
      
        Bitmap offBmp = null;
        Image unFinish,finish, levelNull, level, note, close, clock;
        List<GtdEntryField> tasks = new List<GtdEntryField>();
        DateTime? firstDate = null, lastDate = null;//未用
        Hashtable gtdGroups = new Hashtable();
        GtdEntryField selectedTask = null;
        int scrollwidth = 0;
        int taskRow = 0;
        string newTaskDate = string.Empty;
        int expired = 0;

        AceApplication configApp = Program.AppConfig.App;
        AceGtd configGtd = Program.AppConfig.Gtd;

        GtdGroupField selectedData = null;
        public GtdGroupField SelectedGtdData
        {
            get { return selectedData; }
            set { selectedData = value; }
        }

        private void GtdViewTask_Paint(object sender, PaintEventArgs e)
        {
            e.Graphics.DrawImage(offBmp, 0, 0);
        }

        private void GtdViewTask_Resize(object sender, EventArgs e)
        {
            if (this.Height < 70)
                this.Height = 70;
            if (this.Width < 400)
                this.Width = 400;

            RePaint();
        }


        public void UpdateGtdView(bool refreshData)
        {
            if (refreshData)
                InitTasks();

            selectedTask = null;//移除这个会因为拖动导致新增gtd哪里显示不正确
            RePaint();
        }

        private void RePaint()
        {
            if ((this.ClientRectangle.Width < 1) || (this.ClientRectangle.Height < 1))
                return;

            if ((offBmp == null) || (offBmp.Height != this.ClientRectangle.Height) || (offBmp.Width != this.ClientRectangle.Width))
            {
                if (offBmp != null)
                    offBmp.Dispose();

                offBmp = new Bitmap(this.ClientRectangle.Width, this.ClientRectangle.Height);
            }

            selectedTask = null;
            PaintScroll();
            Graphics g = PaintBackGround();
            PaintNewTask(g);
            PaintTasks(g);
            g.Dispose();
            textBox1.Clear();
            Paint2();
        }

        private void PaintScroll()
        {
            taskRow = (this.Height - 70) / 35;
            int i = tasks.Count - taskRow;
            if (i > 0)
            {
                vScrollBar1.Maximum = i;
                vScrollBar1.Visible = true;
                scrollwidth = 15;
            }
            else
            {
                while (tasks.Count != taskRow)
                    taskRow -= 1;

                vScrollBar1.Visible = false;
                vScrollBar1.Value = 0;
                scrollwidth = 0;
            }
        }

        private Graphics PaintBackGround()
        {
            Graphics g = Graphics.FromImage(offBmp);
            if(configGtd.BackgroundImage==1)
            {
            g.DrawImageUnscaledAndClipped(Properties.Resources.gtd, this.ClientRectangle);
                return g;
            }
            else if (configGtd.BackgroundImage == 2 && System.IO.File.Exists(AppDefines.gtdBackgroupImage))
            {
                g.DrawImageUnscaledAndClipped(Image.FromFile(AppDefines.gtdBackgroupImage), this.ClientRectangle);
                return g;
            }

            g.Clear(Color.White);
            return g;
        }

        private void PaintNewTask(Graphics g)//占70像素
        {
            StringFormat sf = new StringFormat();
            sf.Alignment = StringAlignment.Near;

            FillRectangle(g,Color.Black, 11,10, this.Width - 20 - scrollwidth);
            g.DrawImage(clock, 15, 17);
            if (selectedTask == null)
                g.DrawString(LanguageUtil.双击这里添加新任务, this.Font, Brushes.White, 35, 18);
            else
                g.DrawString(selectedTask.Title, this.Font, Brushes.White,
                    new RectangleF(35, 18, this.Width - 45 - newTaskDate.Length * 8 - scrollwidth, 18));

            g.DrawString(newTaskDate, this.Font, Brushes.White, this.Width - 10 - newTaskDate.Length * 8 - scrollwidth, 18);

            sf.Dispose();
        }

        private void PaintTasks(Graphics g)
        {
            if (tasks.Count == 0)
                return;

            StringFormat sf = new StringFormat();
            //标题
            sf.Alignment = StringAlignment.Center;
            Font f = new System.Drawing.Font("隶书", 18, FontStyle.Bold);
            g.DrawString(LanguageUtil.工作箱, f, Brushes.Black, new Rectangle(0, 45, this.Width, 20), sf);
            if (expired != 0)
            {
                sf.Alignment = StringAlignment.Near;
                f = new System.Drawing.Font("宋体", 10, FontStyle.Bold);
                g.DrawString(expired.ToString() + LanguageUtil.任务已过期, f, Brushes.Blue, new Rectangle(this.Width / 2 + 40, 52, this.Width, 20), sf);
            }
            f.Dispose();


            sf.Alignment = StringAlignment.Near;

            for (int index = 0; index < taskRow; index++)
            {
                if (selectedTask == null)
                {
                    if ((vScrollBar1.Value + index) == tasks.Count)
                        break;
                }
                else
                {
                    //if (tasks[index] == selectedTask)
                    //{
                    //    PaintTask(g, moveTask.X, moveTask.Y, vScrollBar1.Value + index, sf);
                    //    continue;
                    //}
                }

                //所有绘制左内向5像素
                PaintTask(g, 10, index * 35 + 71, vScrollBar1.Value + index, sf);
            }

            sf.Dispose();
        }

        private void PaintTask(Graphics g,int rectangleLeft,int rectangleTop, int rowIndex, StringFormat sf)
        {
            SolidBrush brush;
            int imageTop = rectangleTop + 7;

            if (tasks[rowIndex].Finish)
            {
                FillRectangle(g, Color.LightGray, rectangleLeft, rectangleTop, this.Width - 10 - scrollwidth);
                g.DrawImage(finish, rectangleLeft+5, imageTop);
                brush = new SolidBrush(Color.Black);
            }
            else
            {
                FillRectangle(g, tasks[rowIndex].GtdGroup.ColorBorder, rectangleLeft, rectangleTop, this.Width - 10 - scrollwidth);
                g.DrawImage(unFinish, rectangleLeft + 5, imageTop);
                brush = new SolidBrush(tasks[rowIndex].GtdGroup.ColorText);
            }

            int levelCount = tasks[rowIndex].Level;
            string title = tasks[rowIndex].Title;
            string endTime = tasks[rowIndex].EndTime.ToString(configApp.DateFormat);

            for (int i = 0; i < 5; i++)
            {
                if (levelCount != 0 && i < levelCount)
                    g.DrawImage(level, rectangleLeft + i * 17 + 26, imageTop, 16, 16);
                else
                    g.DrawImage(levelNull, rectangleLeft + i * 17 + 26, imageTop, 16, 16);
            }

            g.DrawImage(close, this.Width - 21 - scrollwidth-rectangleLeft, imageTop);
            g.DrawImage(note, this.Width - 40 - scrollwidth-rectangleLeft, imageTop);

            int padRight = 40 + endTime.Length * 8 + scrollwidth-((rectangleLeft>0)?-rectangleLeft:rectangleLeft);
            if ((this.Width - padRight - 160) > title.Length * 8)
            {
                g.DrawString(title, this.Font, brush, rectangleLeft + 115, imageTop, sf);
                g.DrawString(endTime, this.Font, brush, this.Width - padRight, imageTop, sf);
            }
            else
            {
                g.DrawString(title, this.Font, brush, new RectangleF(rectangleLeft + 115, imageTop, this.Width - padRight - 130, 16));
                g.DrawString(endTime, this.Font, brush, this.Width - padRight, imageTop, sf);
            }

            brush.Dispose();
            //scrollBarValue += 1;
        }

        private void Paint2()
        {
            if ((offBmp == null) || (offBmp.Height != this.ClientRectangle.Height) || (offBmp.Width != this.ClientRectangle.Width))
            {
                RePaint();
                return;
            }
            if ((this.ClientRectangle.Width < 1) || (this.ClientRectangle.Height < 1))
                return;

            if (!this.IsDisposed)//取消这里会导致控件无法刷新,不加验证在切换模式的时候会报错
            {
                Graphics drawingSurface = Graphics.FromHwnd(this.Handle);
                drawingSurface.DrawImage(offBmp, 0, 0);
                drawingSurface.Dispose();
            }
        }


        private void vScrollBar1_ValueChanged(object sender, EventArgs e)
        {
            RePaint();
        }

        private void GtdViewDefault_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button != MouseButtons.Right)
                return;

            if (e.Y > 70)
            {
                int i=vScrollBar1.Value + (e.Y - 70) / 35;
                if(tasks.Count<=i)
                    return;

                selectedTask = tasks[i];
                this.DoDragDrop(selectedTask, DragDropEffects.Copy);
                selectedTask = null;
            }
        }

        private void GtdViewDefault_MouseMove(object sender, MouseEventArgs e)
        {
            if (e.X < 15 || e.X > this.Width - 15 - scrollwidth)
                this.Cursor = Cursors.Default;
            else
            {
                if (e.Y > 17 && e.Y < 32)
                {
                    this.Cursor = Cursors.Hand;
                    return;
                }

                if (expired > 0)//有过期任务才生效
                {
                    if (e.Y > 45 && e.Y < 65)
                    {
                        if (e.X > this.Width / 2 - 27 - scrollwidth && e.X < this.Width / 2 + 110)
                        {
                            this.Cursor = Cursors.Hand;
                            return;
                        }
                    }
                }

                for (int i = 0; i < taskRow; i++)
                {
                    int n = 78 + i * 35;
                    if (e.Y > n && e.Y < n + 16)
                    {
                        this.Cursor = Cursors.Hand;
                        return;
                    }
                }

                this.Cursor = Cursors.Default;
            }
        }

        private void GtdViewDefault_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            if (this.Cursor != Cursors.Hand || e.Button != MouseButtons.Left)
                return;

            int x = e.X;
            if (e.Y < 58)
            {
                if (selectedData == null)
                    return;

                if (x > 35 && x < this.Width - 100)
                {
                    if (selectedTask == null)
                        selectedTask = new GtdEntryField(selectedData.Id);

                    textBox1.Left = 34;
                    textBox1.Top = 17;
                    textBox1.Width = this.Width - 200;
                    textBox1.Visible = true;
                    textBox1.Focus();
                }
            }
            else
            {
                selectedTask = tasks[vScrollBar1.Value + (e.Y - 70) / 35];
                if (selectedTask.Finish)
                    return;

                int padRight = this.Width - 40 - selectedTask.EndTime.ToString(configApp.DateFormat).Length * 8 - scrollwidth;
                if (x > 125 && x < padRight)
                {
                    textBox1.Left = 125;
                    textBox1.Top = (e.Y / 35) * 35 + 8;
                    textBox1.Width = this.Width - 310;
                    textBox1.Text = selectedTask.Title;
                    textBox1.Visible = true;
                    textBox1.Focus();
                }
                else if (x > padRight && x < padRight + selectedTask.EndTime.ToString(configApp.DateFormat).Length * 8)
                    ShowDateForm(x, e.Y);
            }
        }

        private void GtdViewDefault_MouseClick(object sender, MouseEventArgs e)
        {
            if (this.Cursor != Cursors.Hand || e.Button != MouseButtons.Left)
                return;

            int x = e.X;
            if (e.Y < 45)//新增
            {
                if (selectedData == null)
                    return;

                if (x > 15 && x < 31)
                {
                    if (selectedTask == null)
                        selectedTask = new GtdEntryField(selectedData.Id);

                    newTaskDate = ShowDateForm(e.Location.X + this.Location.X, e.Location.Y + this.Location.Y);
                }
            }
            else if (e.Y < 70)
            {
                if (expired > 0)//如果存在过期数据则可以点击标题
                {
                    if (e.X < this.Width / 2 + 30+scrollwidth)
                        UpdateGtdView(true);
                    else
                    {
                        foreach (GtdEntryField task in tasks.FindAll(t => 
                        { return t.Finish || t.EndTime > DateTimeUtil.RemoveTime(DateTime.Now); }))
                            tasks.Remove(task);
                    }
                }
            }
            else
            {
                newTaskDate = string.Empty;
                selectedTask = tasks[vScrollBar1.Value + (e.Y - 70) / 35];
                if (selectedTask.Finish)
                {
                    if (x > this.Width - scrollwidth - 30)//关闭
                    {
                        if (MessageBox.Show(LanguageUtil.操作不可逆_是否继续, "", MessageBoxButtons.YesNo) == DialogResult.No)
                            return;

                        tasks.Remove(selectedTask);
                        selectedTask.Remove();
                        RePaint();
                    }
                    else if (x > this.Width - scrollwidth - 50)//备注
                        OnNoteFormShow(selectedTask);
                    return;
                }

                if (x > 15 && x < 31)//完成
                {
                    selectedTask.Finish = true;
                    TaskSort();
                }
                else if (x > 35 && x < 125)//星星
                {
                    int l = (x - 35) / 16 + 1;
                    if (l == selectedTask.Level)
                        selectedTask.Level = 0;
                    else
                        selectedTask.Level = (int)l;

                    TaskSort();
                }
                else if (x > this.Width - scrollwidth - 30)//关闭
                {
                    if (MessageBox.Show(LanguageUtil.操作不可逆_是否继续, "", MessageBoxButtons.YesNo) == DialogResult.No)
                        return;

                    tasks.Remove(selectedTask);
                    selectedTask.Remove();
                    TaskSort();
                }
                else if (x > this.Width - scrollwidth - 50)//备注
                    OnNoteFormShow(selectedTask);
                else if (x > this.Width - scrollwidth - 42 - selectedTask.EndTime.ToString(configApp.DateFormat).Length * 8)//时间
                {
                    ShowDateForm(e.X - 100, e.Y);
                    TaskSort();
                }
                else
                    selectedTask = null;
           
                if (selectedTask != null)
                    ChangedTask();

            }
            Program.SaveKMD = true;
            RePaint();
        }

        public delegate void ChangedTaskD();
        public event ChangedTaskD ChangedTask;

        private void textBox1_Leave(object sender, EventArgs e)
        {
            textBox1.Visible = false;
            RePaint();
        }

        private void textBox1_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Escape)
            {
                newTaskDate = string.Empty;
                textBox1.Visible = false;
                RePaint();
            }
            else if (e.KeyCode == Keys.Enter)
            {
                selectedTask.Title = textBox1.Text;
                if (textBox1.Top < 50)
                {
                    if (newTaskDate != string.Empty)
                        selectedTask.EndTime = DateTime.ParseExact(newTaskDate, configApp.DateFormat,null);

                    newTaskDate = string.Empty;
                    selectedTask.AddRowToDataTable();
                    tasks.Add(selectedTask);
                    TaskSort();
                }
                ChangedTask();
                textBox1.Visible = false;
                RePaint();
            }
        }

        public override string Text
        {
            get
            {
                return base.Text;
            }
            set
            {
               // newTaskText = Program.Translation.ApplyTo(newTaskText);
              //  boxText = Program.Translation.ApplyTo(boxText);
              // expiredText = Program.Translation.ApplyTo(expiredText);
            }
        }
    }
}
